home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / dev / c / ctags.lha / ctags-3.0.3 / sort.c < prev    next >
C/C++ Source or Header  |  1999-02-17  |  6KB  |  224 lines

  1. /*****************************************************************************
  2. *   $Id: sort.c,v 7.2 1998/12/08 04:21:21 darren Exp $
  3. *
  4. *   Copyright (c) 1996-1998, Darren Hiebert
  5. *
  6. *   This source code is released for free distribution under the terms of the
  7. *   GNU General Public License.
  8. *
  9. *   This module contains functions to sort the tag entries.
  10. *****************************************************************************/
  11.  
  12. /*============================================================================
  13. =   Include files
  14. ============================================================================*/
  15. #include "general.h"
  16.  
  17. #if defined(HAVE_STDLIB_H)
  18. # include <stdlib.h>    /* to declare malloc() */
  19. #endif
  20. #include <string.h>
  21. #include <stdio.h>
  22.  
  23. #include "debug.h"
  24. #include "entry.h"
  25. #include "main.h"
  26. #include "options.h"
  27. #include "read.h"
  28. #include "sort.h"
  29.  
  30. /*============================================================================
  31. =   Function prototypes
  32. ============================================================================*/
  33. #ifndef EXTERNAL_SORT
  34. static void failedSort __ARGS((FILE *const fp));
  35. static int compareTags __ARGS((const void *const one, const void *const two));
  36. static void writeSortedTags __ARGS((char **const table, const size_t numTags, const boolean toStdout));
  37. #endif
  38.  
  39. /*============================================================================
  40. =   Function definitions
  41. ============================================================================*/
  42.  
  43. extern void catFile( name )
  44.     const char *const name;
  45. {
  46.     FILE *const fp = fopen(name, "r");
  47.  
  48.     if (fp != NULL)
  49.     {
  50.     int c;
  51.  
  52.     while ((c = getc(fp)) != EOF)
  53.         putchar(c);
  54.     fclose(fp);
  55.     }
  56. }
  57.  
  58. #ifdef EXTERNAL_SORT
  59.  
  60. extern void externalSortTags( toStdout )
  61.     const boolean toStdout;
  62. {
  63.     const char *const sortTemplate = "%s sort -u -o %s %s";
  64. #ifndef NON_CONST_PUTENV_PROTOTYPE
  65.     const
  66. #endif
  67.       char *const sortOrder = "LC_COLLATE=C";
  68.     const char *env = "";
  69.     const size_t length    = strlen(sortOrder) + strlen(sortTemplate) +
  70.                     2 * strlen(tagFileName());
  71.     char *const cmd = (char *)malloc(length);
  72.     int ret;
  73.  
  74.     if (cmd == NULL)
  75.     ret = -1;
  76.     else
  77.     {
  78.     /*  Ensure ASCII value sort order.
  79.      */
  80. #ifdef HAVE_PUTENV
  81.     putenv(sortOrder);
  82. #else
  83. # ifdef HAVE_SETENV
  84.     setenv("LC_COLLATE", "C", 1);
  85. # else
  86.     env = sortOrder;
  87. # endif
  88. #endif
  89.     sprintf(cmd, sortTemplate, env, tagFileName(), tagFileName());
  90.     ret = system(cmd);
  91.     free(cmd);
  92.  
  93.     }
  94.     if (ret != 0)
  95.     error(FATAL | PERROR, "cannot sort tag file");
  96.     else if (toStdout)
  97.     catFile(tagFileName());
  98. }
  99.  
  100. #else
  101.  
  102. /*----------------------------------------------------------------------------
  103.  *  These functions provide a basic internal sort. No great memory
  104.  *  optimization is performed (e.g. recursive subdivided sorts),
  105.  *  so have lots of memory if you have large tag files.
  106.  *--------------------------------------------------------------------------*/
  107.  
  108. static void failedSort( fp )
  109.     FILE *const fp;
  110. {
  111.     if (fp != NULL)
  112.     fclose(fp);
  113.     error(FATAL | PERROR, "cannot sort tag file");
  114. }
  115.  
  116. static int compareTags( one, two )
  117.     const void *const one;
  118.     const void *const two;
  119. {
  120.     const char *const line1 = *(const char *const *const)one;
  121.     const char *const line2 = *(const char *const *const)two;
  122.  
  123.     return strcmp(line1, line2);
  124. }
  125.  
  126. static void writeSortedTags( table, numTags, toStdout )
  127.     char **const table;
  128.     const size_t numTags;
  129.     const boolean toStdout;
  130. {
  131.     FILE *fp;
  132.     size_t i;
  133.  
  134.     /*    Write the sorted lines back into the tag file.
  135.      */
  136.     if (toStdout)
  137.     fp = stdout;
  138.     else
  139.     {
  140.     fp = fopen(tagFileName(), "w");
  141.     if (fp == NULL)
  142.         failedSort(fp);
  143.     }
  144.     for (i = 0 ; i < numTags ; ++i)
  145.     {
  146.     /*  Here we filter out identical tag *lines* (including search
  147.      *  pattern) if this is not an xref file.
  148.      */
  149.     if (i == 0  ||  Option.xref  ||  strcmp(table[i], table[i-1]) != 0)
  150.         if (fputs(table[i], fp) == EOF)
  151.         failedSort(fp);
  152.     }
  153.     if (! toStdout)
  154.     fclose(fp);
  155. }
  156.  
  157. extern void internalSortTags( toStdout )
  158.     const boolean toStdout;
  159. {
  160.     vString *vLine = vStringNew();
  161.     FILE *fp = NULL;
  162.     const char *line;
  163.     size_t i;
  164.  
  165.     /*    Allocate a table of line pointers to be sorted.
  166.      */
  167.     size_t numTags    = TagFile.numTags.added + TagFile.numTags.prev;
  168.     const size_t tableSize = numTags * sizeof(char *);
  169.     char **const table    = (char **)malloc(tableSize);    /* line pointers */
  170.     DebugStatement( size_t mallocSize = tableSize; )    /* cumulative total */
  171.  
  172.     if (table == NULL)
  173.     failedSort(fp);
  174.  
  175.     /*    Open the tag file and place its lines into allocated buffers.
  176.      */
  177.     fp = fopen(tagFileName(), "r");
  178.     if (fp == NULL)
  179.     failedSort(fp);
  180.     for (i = 0  ;  i < numTags  &&  ! feof(fp)  ;  )
  181.     {
  182.     line = readLine(vLine, fp);
  183.     if (line == NULL)
  184.     {
  185.         if (! feof(fp))
  186.         failedSort(fp);
  187.         break;
  188.     }
  189.     else if (*line == '\0'  ||  strcmp(line, "\n") == 0)
  190.         ;        /* ignore blank lines */
  191.     else
  192.     {
  193.         const size_t stringSize = strlen(line) + 1;
  194.  
  195.         table[i] = (char *)malloc(stringSize);
  196.         if (table[i] == NULL)
  197.         failedSort(fp);
  198.         DebugStatement( mallocSize += stringSize; )
  199.         strcpy(table[i], line);
  200.         ++i;
  201.     }
  202.     }
  203.     numTags = i;
  204.     fclose(fp);
  205.     vStringDelete(vLine);
  206.  
  207.     /*    Sort the lines.
  208.      */
  209.     qsort(table, numTags, sizeof(*table),
  210.       (int (*)__ARGS((const void *, const void *)))compareTags);
  211.  
  212.     writeSortedTags(table, numTags, toStdout);
  213.  
  214.     DebugStatement( if (debug(DEBUG_STATUS))
  215.             printf("sort memory: %ld bytes\n", (long)mallocSize); )
  216.     for (i = 0 ; i < numTags ; ++i)
  217.     free(table[i]);
  218.     free(table);
  219. }
  220.  
  221. #endif
  222.  
  223. /* vi:set tabstop=8 shiftwidth=4: */
  224.